home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / games / IndiZone / oort / vehicle.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  12.9 KB  |  572 lines

  1. /*
  2.  * Copyright (C) 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*------------------------------------------------------------------------------
  18.  *
  19.  * OORT - vehicle.c - Routines for controlling the vehicle.
  20.  *
  21.  * $Id: vehicle.c,v 1.5 1994/02/08 00:10:51 jimh Exp $
  22.  * 
  23.  * Chris Fouts - April, 1993.
  24.  * 
  25.  *----------------------------------------------------------------------------*/
  26.  
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include <unistd.h>
  30.  
  31. #include <pf.h>
  32. #include <prmath.h>
  33. #include <pfutil.h>
  34.  
  35. #include "oort.h"
  36. #include "dashboard.h"
  37. #include "vehicle.h"
  38.  
  39. /* BEGIN PROTOTYPES -S vehicle.c */
  40. static void     adjustSpeed( void ) ;
  41. static void     turnVehicle( float fraction ) ;
  42. /* END PROTOTYPES -S vehicle.c */
  43.  
  44. #define    GRAVITY        (7.5f)    /* Meters/sec/sec */
  45.  
  46. #define    ONE_THIRD    (1.0f/3.0f)
  47. #define    TWO_THIRDS    (2.0f/3.0f)
  48.  
  49. #define    TURN_DEG_PER_SEC    (45.0f)
  50.  
  51. static float        accel ;
  52. extern int        debugOn ;
  53. extern int        markPoint ;
  54. extern Wheel        wheel[3] ;
  55. extern Player        player[1] ;
  56. extern pfVec3        up ;
  57. extern pfVec3        ahead ;
  58. extern pfVec3        right ;
  59. extern float        speed ;
  60. extern float        power ;
  61. extern float        mouseX ;
  62. extern float        mouseY ;
  63. extern float        gameTime ;    /* game time */
  64. extern float        eTime ;        /* elapsed time */
  65. extern int        braking ;
  66. extern int        pausing ;
  67. extern int        landing ;
  68. extern int        orbitalActive ;
  69. extern Motion        motion ;
  70. extern float        idleStartTime ;
  71.  
  72. extern float        accelFactor ;
  73. extern float        topSpeed ;
  74.  
  75.  
  76. /*------------------------------------------------------------------------------
  77.  * Correct the location of the wheels.
  78.  *----------------------------------------------------------------------------*/
  79. void
  80. updateWheels(
  81.     void
  82.     )
  83. {
  84.     pfVec3    v ;
  85.  
  86.     ADDSCALE_VEC3( wheel[FRONT_WHEEL].xyz, motion.cg,
  87.             (float)(TWO_THIRDS*CAR_LENGTH), ahead );
  88.  
  89.     ADDSCALE_VEC3( v, motion.cg, -(float)(ONE_THIRD*CAR_LENGTH), ahead ) ;
  90.  
  91.     ADDSCALE_VEC3( wheel[RREAR_WHEEL].xyz, v, (float)(0.5f*CAR_WIDTH),
  92.             right ) ;
  93.  
  94.     ADDSCALE_VEC3( wheel[LREAR_WHEEL].xyz, v, -(float)(0.5f*CAR_WIDTH),
  95.             right ) ;
  96. }
  97.  
  98.  
  99.  
  100. /*------------------------------------------------------------------------------
  101.  * Turn the vehicle.
  102.  *----------------------------------------------------------------------------*/
  103. static void
  104. turnVehicle(
  105.     float    fraction
  106.     )
  107. {
  108.     int    i ;
  109.     float    sv ;
  110.     float    sta ;
  111.     float    cta ;
  112.     pfVec3    r ;
  113.     pfVec3    a ;
  114.  
  115.     if( wheel[FRONT_WHEEL].inAir == 0 || landing )
  116.     {
  117.         if( landing )
  118.         {
  119.             pfSinCos( fraction * TURN_DEG_PER_SEC * eTime,
  120.                     &sta, &cta ) ;
  121.         }
  122.         else if( speed > 0.0f )
  123.         {
  124.             pfSinCos( fraction * TURN_DEG_PER_SEC * eTime *
  125.                 ( 0.25 + speed / topSpeed ), &sta, &cta ) ;
  126.         }
  127.         else if( speed < 0.0f )
  128.         {
  129.             pfSinCos( fraction * TURN_DEG_PER_SEC * eTime *
  130.                 ( 0.25 - speed / topSpeed ), &sta, &cta ) ;
  131.         }
  132.         else if( !braking )
  133.         {
  134.             pfSinCos( fraction * TURN_DEG_PER_SEC * eTime * 0.50f,
  135.                     &sta, &cta ) ;
  136.         }
  137.         else
  138.         {
  139.             return ;
  140.         }
  141.  
  142.         PFCOPY_VEC3( r, right ) ;
  143.         PFCOPY_VEC3( a, ahead ) ;
  144.  
  145.         PFCOMBINE_VEC3( right, cta, r, -sta, a ) ;
  146.         PFCOMBINE_VEC3( ahead, sta, r,  cta, a ) ;
  147.  
  148.         updateWheels() ;
  149.     }
  150. }
  151.  
  152.  
  153.  
  154. /*------------------------------------------------------------------------------
  155.  * Update the speed.
  156.  *----------------------------------------------------------------------------*/
  157. static void
  158. adjustSpeed(
  159.     void
  160.     )
  161. {
  162.     float    pr ;
  163.     float    newSpeed ;
  164.  
  165.     if( wheel[FRONT_WHEEL].inAir + wheel[RREAR_WHEEL].inAir +
  166.         wheel[LREAR_WHEEL].inAir != 3 )
  167.     {
  168.         newSpeed = speed + eTime * accel ;
  169.         /*
  170.          * Stop at 0.0 so we can come to a standstill.
  171.          */
  172.         if( newSpeed * speed < 0.0f )
  173.         {
  174.             speed = 0.0f ;
  175.         }
  176.         else
  177.         {
  178.             if( newSpeed > topSpeed )
  179.             {
  180.                 speed = topSpeed ;
  181.             }
  182.             else if( newSpeed < -0.5f * topSpeed )
  183.             {
  184.                 speed = -0.5f * topSpeed ;
  185.             }
  186.             else
  187.             {
  188.                 speed = newSpeed ;
  189.             }
  190.         }
  191.         accel = 0.0f ;
  192.     }
  193.  
  194.     pr = speedPowerReq() ;
  195.     if( pr > power )
  196.         speed *= power / pr ;
  197. }
  198.  
  199.  
  200.  
  201. /*------------------------------------------------------------------------------
  202.  * Determine the intersection point with the ground.
  203.  *----------------------------------------------------------------------------*/
  204. void
  205. getDistanceToGround(
  206.     pfGroup    *node,
  207.     pfVec3    intersection[3],
  208.     pfVec3    n[3],
  209.     pfVec3    pt0,
  210.     pfVec3    pt1,
  211.     pfVec3    pt2
  212.     )
  213. {
  214.     int    i ;
  215.     long    k ;
  216.     pfVec3    center ;
  217.     pfVec3    v[3] ;
  218.     pfSegSet    segSet ;
  219.     pfSeg    iSegs[3] ;
  220.     pfSeg    *segs[3] ;
  221.     pfHit    **hits[3] ;
  222.  
  223.     PFSET_VEC3( center, 0.0f, 0.0f, 0.0f ) ;
  224.     PFSCALE_VEC3( v[0], 1.5f, pt0 ) ;
  225.     pfMakePtsSeg( &iSegs[0], v[0], center ) ;
  226.  
  227.     PFSCALE_VEC3( v[1], 1.5f, pt1 ) ;
  228.     pfMakePtsSeg( &iSegs[1], v[1], center ) ;
  229.  
  230.     PFSCALE_VEC3( v[2], 1.5f, pt2 ) ;
  231.     pfMakePtsSeg( &iSegs[2], v[2], center ) ;
  232.  
  233.     segSet.segs[0] = iSegs[0] ;
  234.     segSet.segs[1] = iSegs[1] ;
  235.     segSet.segs[2] = iSegs[2] ;
  236.     segSet.activeMask = 0x07 ;
  237.     segSet.mode = PFTRAV_IS_PRIM | PFTRAV_IS_NORM ;
  238.     segSet.isectMask = GROUND_MASK ;
  239.     segSet.bound = NULL ;
  240.     segSet.discFunc = NULL ;
  241.     segSet.userData = NULL ;
  242.  
  243.     k = pfSegsIsectNode( node, &segSet, hits ) ;
  244.  
  245.     for( i = 0 ; i < 3 ; i++ )
  246.     {
  247.         pfVec3    point ;
  248.         long    flags ;
  249.  
  250.         pfQueryHit( hits[i][0], PFQHIT_FLAGS, &flags ) ;
  251.         if( flags & PFHIT_POINT )
  252.         {
  253.             pfQueryHit( hits[i][0], PFQHIT_POINT, point ) ;
  254.             PFCOPY_VEC3( intersection[i], point ) ;
  255.         }
  256.         else
  257.         {
  258.             PFCOPY_VEC3( intersection[i],
  259.             ( i == 0 ) ? pt0 : ( ( i == 1 ) ? pt1 : pt2 ) ) ;
  260.         }
  261.         if( flags & PFHIT_NORM )
  262.         {
  263.             pfQueryHit( hits[i][0], PFQHIT_NORM, point ) ;
  264.             PFCOPY_VEC3( n[i], point ) ;
  265.         }
  266.         else
  267.         {
  268.             PFCOPY_VEC3( n[i], intersection[i] ) ;
  269.             pfNormalizeVec3( n[i] ) ;
  270.         }
  271.     }
  272. }
  273.  
  274.  
  275.  
  276. /*------------------------------------------------------------------------------
  277.  * Move own vehicle one frame.
  278.  *----------------------------------------------------------------------------*/
  279. void
  280. moveSelf(
  281.     pfGroup    *node
  282.     )
  283. {
  284.     int        i ;
  285.     float        sn ;
  286.     float        va ;
  287.     float        vr ;
  288.     float        vu ;
  289.     float        f ;
  290.     pfVec3        u ;
  291.     pfVec3        oldVel ;
  292.     pfVec3        d ;
  293.     pfVec3        g ;
  294.     pfVec3        n[3] ;
  295.     pfVec3        v[3] ;
  296.     int        wheelsOnGround ;
  297.     static int    airBorne = 0 ;
  298.     static int    idleFlag = 0 ;
  299.  
  300.     /*
  301.      * Check to turn vehicle.
  302.      */
  303.     if( mouseX < -0.2f )
  304.     {
  305.         turnVehicle( ( mouseX + 0.2f ) / 0.8f ) ;
  306.     }
  307.     else if( mouseX > 0.2f )
  308.     {
  309.         turnVehicle( ( mouseX - 0.2f ) / 0.8f ) ;
  310.     }
  311.  
  312.     /*
  313.      * Advance vehicle.
  314.      */
  315.     adjustSpeed() ;
  316.  
  317. #ifdef DEBUG
  318.     if( !landing && ABS( speed ) < 0.10f * MAX_SPEED && orbitalActive )
  319. #else
  320.     if( !landing && ABS( speed ) < 0.10f * MAX_SPEED )
  321. #endif /* DEBUG */
  322.     {
  323.         if( idleFlag == 0 )
  324.         {
  325.             idleFlag = 1 ;
  326.             idleStartTime = gameTime ;
  327.         }
  328.     }
  329.     else
  330.     {
  331.         idleStartTime = gameTime ;
  332.     }
  333.  
  334.     /*
  335.      * Remove side velocities.
  336.      */
  337.     wheelsOnGround = 0 ;
  338.     for( i = 0 ; i < 3 ; i++ )
  339.     {
  340.         if( !wheel[i].inAir )
  341.         {
  342.             sn = PFDOT_VEC3( wheel[i].vel, right ) ;
  343.             wheel[i].vel[0] -= sn * right[0] ;
  344.             wheel[i].vel[1] -= sn * right[1] ;
  345.             wheel[i].vel[2] -= sn * right[2] ;
  346.             wheelsOnGround++ ;
  347.         }
  348.     }
  349.  
  350.     if( speed == 0.0f && wheelsOnGround == 3 )
  351.     {
  352.         PFSET_VEC3( wheel[FRONT_WHEEL].vel, 0.0f, 0.0f, 0.0f ) ;
  353.         PFSET_VEC3( wheel[RREAR_WHEEL].vel, 0.0f, 0.0f, 0.0f ) ;
  354.         PFSET_VEC3( wheel[LREAR_WHEEL].vel, 0.0f, 0.0f, 0.0f ) ;
  355.         return ;
  356.     }
  357.  
  358.     /*
  359.      * Set velocity component along "ahead" direction equal to
  360.      * "speed".
  361.      */
  362.     f = speed - PFDOT_VEC3( wheel[FRONT_WHEEL].vel, ahead ) ;
  363.     OFFSET_VEC3( wheel[FRONT_WHEEL].vel, f, ahead ) ;
  364.     f = speed - PFDOT_VEC3( wheel[RREAR_WHEEL].vel, ahead ) ;
  365.     OFFSET_VEC3( wheel[RREAR_WHEEL].vel, f, ahead ) ;
  366.     f = speed - PFDOT_VEC3( wheel[LREAR_WHEEL].vel, ahead ) ;
  367.     OFFSET_VEC3( wheel[LREAR_WHEEL].vel, f, ahead ) ;
  368.  
  369.     /*
  370.      * Add gravity effect to wheels.
  371.      */
  372.     PFCOPY_VEC3( g, motion.cg ) ;
  373.     pfNormalizeVec3( g ) ;
  374.     PFSCALE_VEC3( g, -GRAVITY * eTime, g ) ;
  375.     PFADD_VEC3( wheel[FRONT_WHEEL].vel, wheel[FRONT_WHEEL].vel, g ) ;
  376.     PFADD_VEC3( wheel[RREAR_WHEEL].vel, wheel[RREAR_WHEEL].vel, g ) ;
  377.     PFADD_VEC3( wheel[LREAR_WHEEL].vel, wheel[LREAR_WHEEL].vel, g ) ;
  378.  
  379.     /*
  380.      * Move wheels.
  381.      */
  382.     OFFSET_VEC3( wheel[FRONT_WHEEL].xyz, eTime, wheel[FRONT_WHEEL].vel ) ;
  383.     OFFSET_VEC3( wheel[RREAR_WHEEL].xyz, eTime, wheel[RREAR_WHEEL].vel ) ;
  384.     OFFSET_VEC3( wheel[LREAR_WHEEL].xyz, eTime, wheel[LREAR_WHEEL].vel ) ;
  385.  
  386.     /*
  387.      * Check for distance to ground.
  388.      */
  389.     getDistanceToGround( node, v, n, wheel[0].xyz,
  390.         wheel[1].xyz, wheel[2].xyz ) ;
  391.  
  392.     /*
  393.      * React wheel with ground.
  394.      */
  395.     wheelsOnGround = 0 ;
  396.     for( i = 0 ; i < 3 ; i++ )
  397.     {
  398.         PFSUB_VEC3( d, wheel[i].xyz, v[i] ) ;
  399.  
  400.         if( PFDOT_VEC3( d, n[i] ) < 0.25f )
  401.         {
  402.             PFCOPY_VEC3( wheel[i].xyz, v[i] ) ;
  403.             wheel[i].inAir = 0 ;
  404.  
  405.             /*
  406.              * Adjust velocity (bounce if into ground).
  407.              */
  408.             sn = PFDOT_VEC3( wheel[i].vel, n[i] ) ;
  409.             if( sn < 0.0f )
  410.             {
  411.                 sn *= -1.1 ;
  412.                 OFFSET_VEC3( wheel[i].vel, sn, n[i] ) ;
  413.             }
  414.             else
  415.             {
  416.                 PFSET_VEC3( wheel[i].vel, 0.0f, 0.0f, 0.0f ) ;
  417.             }
  418.             wheelsOnGround++ ;
  419.             airBorne = 0 ;
  420.         }
  421.         else
  422.         {
  423.             wheel[i].inAir = 1 ;
  424.         }
  425.     }
  426.  
  427.     /*
  428.      * If one wheel touches down, set velocities to zero so we don't bounce.
  429.      */
  430.     if( landing && wheelsOnGround )
  431.     {
  432.         PFSET_VEC3( wheel[FRONT_WHEEL].vel, 0.0f, 0.0f, 0.0f ) ;
  433.         PFSET_VEC3( wheel[RREAR_WHEEL].vel, 0.0f, 0.0f, 0.0f ) ;
  434.         PFSET_VEC3( wheel[LREAR_WHEEL].vel, 0.0f, 0.0f, 0.0f ) ;
  435.         landing = 0 ;
  436.     }
  437.  
  438.     PFCOPY_VEC3( oldVel, motion.vel ) ;
  439.  
  440.     /*
  441.      * Update main velocity.
  442.      */
  443.     motion.vel[0]= ( wheel[FRONT_WHEEL].vel[0] + wheel[RREAR_WHEEL].vel[0] +
  444.             wheel[LREAR_WHEEL].vel[0] ) / 3.0f ;
  445.     motion.vel[1]= ( wheel[FRONT_WHEEL].vel[1] + wheel[RREAR_WHEEL].vel[1] +
  446.             wheel[LREAR_WHEEL].vel[1] ) / 3.0f ;
  447.     motion.vel[2]= ( wheel[FRONT_WHEEL].vel[2] + wheel[RREAR_WHEEL].vel[2] +
  448.             wheel[LREAR_WHEEL].vel[2] ) / 3.0f ;
  449.  
  450.     /*
  451.      * Compute delta velocity components along up, right, and ahead vectors.
  452.      */
  453.     PFSUB_VEC3( d, motion.vel, oldVel ) ;
  454.     vu = PFDOT_VEC3( up, d ) ;
  455.     vr = PFDOT_VEC3( right, d ) ;
  456.     va = PFDOT_VEC3( ahead, d ) ;
  457.  
  458.     /*
  459.      * Update direction vectors.
  460.      */
  461.     PFSUB_VEC3( right, wheel[RREAR_WHEEL].xyz, wheel[LREAR_WHEEL].xyz ) ;
  462.     pfNormalizeVec3( right ) ;
  463.  
  464.     PFCOMBINE_VEC3( u, 0.5f, wheel[RREAR_WHEEL].xyz,
  465.               0.5f, wheel[LREAR_WHEEL].xyz ) ;
  466.  
  467.     PFSUB_VEC3( ahead, wheel[FRONT_WHEEL].xyz, u ) ;
  468.     f = -PFDOT_VEC3( ahead, right ) ;
  469.     OFFSET_VEC3( ahead, f, right );
  470.     pfNormalizeVec3( ahead ) ;
  471.  
  472.     /*
  473.      * Smooth rotation of up vector to simulate shocks.
  474.      */
  475.     pfCrossVec3( u, right, ahead ) ;
  476.     PFCOMBINE_VEC3( up, 0.60f, up, 0.40f, u ) ;
  477.     f = -PFDOT_VEC3( up, right ) ;
  478.     OFFSET_VEC3( up, f, right );
  479.     pfNormalizeVec3( up ) ;
  480.     pfCrossVec3( ahead, up, right ) ;
  481.  
  482.     /*
  483.      * Update center of gravity.
  484.      */
  485.     motion.cg[0] = ( wheel[FRONT_WHEEL].xyz[0] + wheel[RREAR_WHEEL].xyz[0] +
  486.             wheel[LREAR_WHEEL].xyz[0] ) / 3.0f ;
  487.     motion.cg[1] = ( wheel[FRONT_WHEEL].xyz[1] + wheel[RREAR_WHEEL].xyz[1] +
  488.             wheel[LREAR_WHEEL].xyz[1] ) / 3.0f ;
  489.     motion.cg[2] = ( wheel[FRONT_WHEEL].xyz[2] + wheel[RREAR_WHEEL].xyz[2] +
  490.             wheel[LREAR_WHEEL].xyz[2] ) / 3.0f ;
  491.  
  492.     /*
  493.      * Update wheel locations relative to center of gravity.
  494.      */
  495.     updateWheels() ;
  496.  
  497.     /*
  498.      * If up in the air, set all wheel velocities to the same value
  499.      * to avoid the flipping-funkiness that happens otherwise.
  500.      */
  501.     if( wheelsOnGround == 0 && !airBorne && !landing )
  502.     {
  503.         airBorne = 1 ;
  504.  
  505.         PFCOPY_VEC3( wheel[FRONT_WHEEL].vel, motion.vel ) ;
  506.         PFCOPY_VEC3( wheel[RREAR_WHEEL].vel, motion.vel ) ;
  507.         PFCOPY_VEC3( wheel[LREAR_WHEEL].vel, motion.vel ) ;
  508.         PFSCALE_VEC3( g, 0.5f, g ) ;
  509.         if( PFDOT_VEC3( ahead, motion.vel ) < 0.0f )
  510.         {
  511.             PFADD_VEC3( wheel[RREAR_WHEEL].vel,
  512.                 wheel[RREAR_WHEEL].vel, g ) ;
  513.             PFADD_VEC3( wheel[LREAR_WHEEL].vel,
  514.                 wheel[LREAR_WHEEL].vel, g ) ;
  515.         }
  516.         else
  517.         {
  518.             PFADD_VEC3( wheel[FRONT_WHEEL].vel,
  519.                 wheel[FRONT_WHEEL].vel, g ) ;
  520.         }
  521.         /*
  522.          * Recalc mean velocity.
  523.          */
  524.         motion.vel[0]= ( wheel[FRONT_WHEEL].vel[0] +
  525.                 wheel[RREAR_WHEEL].vel[0] +
  526.                 wheel[LREAR_WHEEL].vel[0] ) / 3.0f ;
  527.         motion.vel[1]= ( wheel[FRONT_WHEEL].vel[1] +
  528.                 wheel[RREAR_WHEEL].vel[1] +
  529.                 wheel[LREAR_WHEEL].vel[1] ) / 3.0f ;
  530.         motion.vel[2]= ( wheel[FRONT_WHEEL].vel[2] +
  531.                 wheel[RREAR_WHEEL].vel[2] +
  532.                 wheel[LREAR_WHEEL].vel[2] ) / 3.0f ;
  533.     }
  534. }
  535.  
  536.  
  537.  
  538. /*------------------------------------------------------------------------------
  539.  * Modify the vehicle acceleration.
  540.  *----------------------------------------------------------------------------*/
  541. void
  542. changeAcceleration(
  543.     float    factor
  544.     )
  545. {
  546.     accel = 2.0f * factor * accelFactor ;
  547. }
  548.  
  549.  
  550.  
  551. /*------------------------------------------------------------------------------
  552.  * Apply the brakes.
  553.  *----------------------------------------------------------------------------*/
  554. void
  555. applyBrakes(
  556.     void
  557.     )
  558. {
  559.     if( speed > 0.0f )
  560.     {
  561.         accel = -5.0f * accelFactor ;
  562.     }
  563.     else if( speed < 0.0f )
  564.     {
  565.         accel = 5.0f * accelFactor ;
  566.     }
  567.     else
  568.     {
  569.         accel = 0.0f ;
  570.     }
  571. }
  572.